home *** CD-ROM | disk | FTP | other *** search
/ CDUTIL 13 / CDUTIL #13 Julio 1995.iso / windows / acadcom / ads / sample / sqr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  6.0 KB  |  201 lines

  1. /* Next available MSG number is   6 */
  2.  
  3. /*    
  4.  
  5.    SQR.C
  6.  
  7.    Copyright (C) 1990, 1991, 1992, 1993, 1994 by Autodesk, Inc.
  8.  
  9.    Permission to use, copy, modify, and distribute this software in 
  10.    object code form for any purpose and without fee is hereby granted, 
  11.    provided that the above copyright notice appears in all copies and 
  12.    that both that copyright notice and the limited warranty and 
  13.    restricted rights notice below appear in all supporting 
  14.    documentation.
  15.  
  16.    AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.  
  17.    AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF 
  18.    MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
  19.    DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE 
  20.    UNINTERRUPTED OR ERROR FREE.
  21.  
  22.    Use, duplication, or disclosure by the U.S. Government is subject to 
  23.    restrictions set forth in FAR 52.227-19 (Commercial Computer 
  24.    Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) 
  25.    (Rights in Technical Data and Computer Software), as applicable.
  26.     
  27.    .
  28.  
  29.  **********************************************************************
  30.  * ADS SQUARE ROOT application - by Mark Barrow - 3/14/90
  31.  * Comments and revisions - Randy Clark, 4/23/90
  32.  **********************************************************************
  33.  */
  34.  
  35. #include  <stdio.h>
  36. #include  <math.h>
  37. #include  "adslib.h"
  38.  
  39. #define ExtFuncCount    1             /* Must increase this count if new
  40.                                          external functions are added */
  41.  
  42. int funcload _((void));
  43. int funcunload _((void));
  44. int dofun _((void));
  45.  
  46. char *exfun[] = {/*MSG0*/"sqr"};      /* No "C:" -- to be called as an AutoLISP
  47.                                          function, not as an AutoCAD command */
  48.  
  49. /* More functions could be added to this table.  For example:
  50.    char *exfun[] = {"C:sqr", "C:shaft", "PIN"}; */
  51.  
  52. /*-----------------------------------------------------------------------*/
  53. /* MAIN - the main routine */
  54.  
  55. void main(argc,argv)
  56.   int argc; char *argv[];
  57. {
  58.     short scode = RSRSLT;             /* Normal result code (default) */
  59.     int stat;
  60.     char errmsg[80];
  61.  
  62.     ads_init(argc, argv);             /* Initiate communication with AutoLISP */
  63.  
  64.     for ( ;; ) {                      /* Request/Result loop */
  65.  
  66.         if ((stat = ads_link(scode)) < 0) {
  67.             sprintf(errmsg, /*MSG1*/"SQRT: bad status from ads_link() = %d\n",
  68.                     stat);
  69. #ifdef Macintosh
  70.             macalert(errmsg);
  71. #else
  72.             puts(errmsg);
  73.             fflush(stdout);
  74. #endif /* Macintosh */
  75.             exit(1);
  76.         }
  77.  
  78.         scode = RSRSLT;               /* Reset result code */
  79.  
  80.         switch (stat) {
  81.  
  82.         case RQXLOAD:                 /* Load & define functions */
  83.             scode = funcload() ? -RSRSLT : -RSERR;
  84.             break;
  85.  
  86.         case RQXUNLD:                 /* Unload functions */
  87.             scode = funcunload() ? -RSRSLT : -RSERR;
  88.             ads_printf(/*MSG2*/"Unloading.\n");
  89.             break;
  90.  
  91.         case RQSUBR:                  /* Handle request for external function */
  92.             scode = dofun() ? RSRSLT : RSERR;
  93.             break;
  94.  
  95.         default:
  96.             break;
  97.         }
  98.     }
  99. }
  100. /*-----------------------------------------------------------------------*/
  101. /* FUNCLOAD  --  Define this application's external functions  */
  102.  
  103. int funcload()
  104. {
  105.     int i;
  106.     for (i = 0; i < ExtFuncCount; i++) {
  107.         if (!ads_defun(exfun[i], i))
  108.             return RTERROR;
  109.     }
  110.     return RTNORM;
  111. }
  112. /*-----------------------------------------------------------------------*/
  113. /* FUNCUNLOAD  --  Unload external functions */
  114.  
  115. int funcunload()
  116. {
  117.     int i;
  118.  
  119.     /* Undefine each function we defined */
  120.  
  121.     for (i = 0; i < ExtFuncCount; i++) {
  122.         ads_undef(exfun[i],i);
  123.     }
  124.     return RTNORM;
  125. }
  126. /*-----------------------------------------------------------------------*/
  127. /* DOFUN -- Execute external function (called upon an RQSUBR request) */
  128.  
  129. int dofun()
  130. {
  131.     struct resbuf *rb;
  132.     int val;
  133.     ads_real x;
  134.     extern ads_real rsqr _((ads_real));
  135.  
  136.     if ((val = ads_getfuncode()) < 0)
  137.         return 0;
  138.  
  139.     if ((rb = ads_getargs()) == NULL)
  140.         return 0;
  141.  
  142.     switch (val) {                    /* The 'sqr' function was defined
  143.                                          to have a funcode of 0 */
  144.  
  145.     case 0:
  146.         if (rb->restype == RTSHORT) {   /* Save in local variable */
  147.             x = (ads_real) rb->resval.rint;
  148.         } else if (rb->restype == RTREAL) {
  149.             x = rb->resval.rreal;     /* Can accept either real
  150.                                          or integer */
  151.         } else {
  152.             ads_fail(/*MSG3*/"Argument should be a real or integer value.");
  153.             return 0;
  154.         }
  155.         if (x < 0) {                  /* Check argument range */
  156.             ads_fail(/*MSG4*/"Argument should be positive.");
  157.             return 0;
  158.         }
  159.  
  160.         ads_retreal(rsqr(x));         /* Call the function itself, and
  161.                                          return the value to AutoLISP */
  162.  
  163.         return 1;
  164.  
  165.     default:
  166.         ads_fail(/*MSG5*/"Received nonexistent function code.");
  167.         return 0;
  168.     }
  169. }
  170. /*-----------------------------------------------------------------------*/
  171. /* This is the implementation of the actual external function */
  172.  
  173. ads_real rsqr(x)              /* Figure square root (Newton-Raphson method) */
  174.   ads_real x;
  175. {
  176.     ads_real y, c, cl;
  177.     int n;
  178.  
  179.     if (x == 0.0) {
  180.         return 0.0;
  181.     }
  182.  
  183. #ifdef __STDC__
  184.     y = frexp(x, &n);        /* split x to get exponent */
  185.     y = ldexp(1.0, n / 2);   /* good guess at sqrt */
  186.     n = 10;                  /* it will converge faster than this */
  187. #else
  188.     y = (0.154116 + 1.893872 * x) / (1.0 + 1.047988 * x);
  189.     /* It takes a lot of iterations to get sqrt(1E22) from
  190.        an initial guess of 1.9 */
  191.     n = 50;
  192. #endif
  193.     c = 0.0;
  194.     do {
  195.         cl = c;
  196.         c = (y - x / y) * 0.5;
  197.         y -=  c;
  198.     } while (c != cl && --n);
  199.     return y;
  200. }
  201.